package com.skymobi.netty.demo.biz;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xj.toolkit.base.Sender;
import xj.toolkit.base.TransportUtils;
import xj.toolkit.bean.AbstractCommonBean;
import xj.toolkit.ebus.EventBus;
import xj.toolkit.fsm.FSMContext;
import xj.toolkit.fsm.FiniteStateMachine;
import xj.toolkit.fsm.tmpl.annotation.OnEnter;
import xj.toolkit.fsm.tmpl.annotation.StateTemplate;

public abstract class BaseBiz<Q extends AbstractCommonBean, T extends AbstractCommonBean> {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    protected static final Logger timeoutLogger = LoggerFactory.getLogger("timeoutLogger");
    public static final String FSM_CONTEXT_REQ = "REQUEST";
    public static final String FSM_CONTEXT_REP = "RESPONSE";

    protected EventBus eventBus;
    protected int timeout;

    protected T initTcpResponse(FSMContext ctx, AbstractCommonBean request, T response) {
        response.setIdentification(request.getIdentification());
        setRequest(ctx, request);
        setResponse(ctx, response);
        return response;
    }

    @StateTemplate
    class SendResp {
        @OnEnter
        boolean enter(FiniteStateMachine fsm, FSMContext ctx) {
            // 处理向client返回
            if (getResponse(ctx) != null) {
                Object request = getRequest(ctx);
                AbstractCommonBean response = getResponse(ctx);
                // send response
                Sender sender = TransportUtils.getSenderOf(request);
                if (logger.isDebugEnabled()) {
                    logger.debug("SendClientRespState={}", response);
                }
                if (sender != null) {
                    sender.send(request, response);
                } else {
                    logger.error("getSender error!");
                }
                if (ctx.getEndReason() == null) {
                    ctx.setEndReason(request.getClass().getSimpleName());
                }
                return false;
            } else {
                logger.error("getResponse error!");
                return false;
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected Q getRequest(FSMContext ctx) {
        return (Q) ctx.getProperty(FSM_CONTEXT_REQ);
    }

    protected void setRequest(FSMContext ctx, Object request) {
        ctx.setProperty(FSM_CONTEXT_REQ, request);
    }

    @SuppressWarnings("unchecked")
    protected T getResponse(FSMContext ctx) {
        return (T) ctx.getProperty(FSM_CONTEXT_REP);
    }

    protected void setResponse(FSMContext ctx, T response) {
        ctx.setProperty(FSM_CONTEXT_REP, response);
    }

    public EventBus getEventBus() {
        return eventBus;
    }

    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
}
